package org.smile.strate;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

@SuppressWarnings("unchecked")
/**
 * @author 胡真山
 */
public class ActionContext {
	
protected final static Logger logger = Logger.getLogger(ActionContext.class.getName());
	/**
	 * 保存文件中配置的所有的bean名字与类名对应
	 */
	public static Map<String,ActionElement> actionsMap;
	
	static {
		InputStream is=null;
		try{
			actionsMap=new HashMap();
			is=ActionContext.class.getClassLoader().getResourceAsStream("strate.xml");
			Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
			//解析当前文件的action
			parseAction(doc);
			//解析include文件
			NodeList nodeList = doc.getElementsByTagName("include");
			int length=nodeList.getLength();
			Element element;
			for(int i=0;i<length;i++){
				element = (Element) nodeList.item(i);
				String filename=element.getAttribute("file");
				InputStream fileIs=null;
				try{
					fileIs=ActionContext.class.getClassLoader().getResourceAsStream(filename);
					Document includeDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(fileIs);
					parseAction(includeDoc);
				}catch(Exception e){
					logger.error("读取文件 strate.xml include file "+filename+"throw a exception ",e);
				}finally{
					if(fileIs!=null){
						fileIs.close();
					}
				}
			}
			logger.info("strate配置文件加载完成:[strate.xml]"+actionsMap);
		}
		catch(Exception e)
		{
			logger.error("servlet配置文件加载失败:",e);
		}finally{
			if(is!=null){
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	/**
	 * 解析Document中的所有action标签
	 * @param doc
	 * @throws Exception
	 */
	private static void parseAction(Document doc) throws Exception{
		NodeList nodeList = doc.getElementsByTagName("package");
		int length=nodeList.getLength();
		//解析每一个包
		Element element;
		Element action;
		Element forward;
		ActionElement actionElement;
		ActionForward actionForward;
		for(int i=0;i<length;i++){
			element = (Element) nodeList.item(i);
			String namespace=element.getAttribute("namespace");
			NodeList actions=element.getElementsByTagName("action");
			//解析分一个action
			for(int j=0;j<actions.getLength();j++){
				action=(Element)actions.item(j);
				actionElement=new ActionElement();
				actionElement.setName(action.getAttribute("name"));
				actionElement.setClazz(action.getAttribute("class"));
				actionElement.setSpace(namespace);
				actionElement.setMethod(action.getAttribute("method"));
				NodeList forwards=action.getElementsByTagName("forward");
				//解析forward
				for(int k=0;k<forwards.getLength();k++){
					forward=(Element)forwards.item(k);
					actionForward=new ActionForward();
					actionForward.setName(forward.getAttribute("name"));
					actionForward.setType(forward.getAttribute("type"));
					actionForward.setResult(forward.getTextContent());
					actionElement.putForward(actionForward);
				}
				actionsMap.put(namespace+actionElement.getName(), actionElement);
			}
		}
	}
	/**
	 * 获取一个action的配置对象
	 * @param url
	 * @return
	 */
	public static ActionElement getActionElement(String url)
	{
		return actionsMap.get(url) ;
	}
}
